#include <netlib/packet/PacketQueue.h>
#include <utility>

using namespace netlib::packet;

PacketQueue::PacketQueue(size_t capacity) : m_buffer( capacity, true ), m_size( 0 )
{
}

PacketQueue::~PacketQueue()
{
}

bool PacketQueue::pop(SocketEvent *socketEvent)
{
	if (0 == m_size)
		return ( false );

	m_buffer.read(reinterpret_cast< unsigned char * >( &socketEvent->m_event ), sizeof( DispatchEvent ) );
	m_buffer.read(reinterpret_cast< unsigned char * >( &socketEvent->m_errorCode ), sizeof( int ) );
	m_buffer.read(reinterpret_cast< unsigned char * >( &socketEvent->m_size ), sizeof( size_t ) );

	if ( socketEvent->m_size > 0 )
	{
		socketEvent->m_ptr = m_buffer.beginOfBuffer();
		m_buffer.offset( socketEvent->m_size );
	}
	
	--m_size;

	return ( true );
}

size_t PacketQueue::size() const
{
	return ( m_size );
}

bool PacketQueue::empty() const
{
	return (0 == m_size);
}

bool PacketQueue::push(DispatchEvent dispatchEvent, unsigned char *ptr, size_t size, int errorCode)
{
	if ( m_buffer.remainSize() <= sizeof( SocketEvent ) + size )
		m_buffer.resize();

	m_buffer.write(reinterpret_cast< unsigned char * >( &dispatchEvent ), sizeof( DispatchEvent ) );
	m_buffer.write(reinterpret_cast< unsigned char * >( &errorCode ), sizeof( int ) );
	m_buffer.write(reinterpret_cast< unsigned char * >( &size ), sizeof( size_t ) );

	if ( NULL != ptr )
		m_buffer.write( ptr, size );

	++m_size;

	return true;
}

void PacketQueue::clear()
{
	m_size = 0;
	m_buffer.reset();
}
